package org.light.simpleauth;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.light.complexverb.AddUploadDomainField;
import org.light.complexverb.DomainFieldVerb;
import org.light.core.AxumController;
import org.light.core.AxumPlainLoginController;
import org.light.core.AxumPlainProfileController;
import org.light.core.Module;
import org.light.core.PrismInterface;
import org.light.core.Verb;
import org.light.domain.Controller;
import org.light.domain.DaoImpl;
import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.DummyDaoImpl;
import org.light.domain.Field;
import org.light.domain.ManyToMany;
import org.light.domain.Method;
import org.light.domain.Prism;
import org.light.domain.ServiceImpl;
import org.light.domain.ValidateInfo;
import org.light.easyuilayouts.widgets.Nav;
import org.light.exception.ValidateException;
import org.light.layouts.EasyUIGridPagePI;
import org.light.layouts.EasyUIMtmPI;
import org.light.limitedverb.CountActiveRecords;
import org.light.limitedverb.CountAllPage;
import org.light.limitedverb.CountSearchByFieldsRecords;
import org.light.limitedverb.DaoOnlyVerb;
import org.light.limitedverb.NoControllerVerb;
import org.light.simpleauth.easyui.EasyUIErrorPI;
import org.light.simpleauth.easyui.EasyUILoginUserIndexPI;
import org.light.simpleauth.easyui.EasyUIProfilePI;
import org.light.simpleauth.easyui.EasyUIRegisterUserPI;
import org.light.simpleauth.easyui.EasyUIUserPagePI;
import org.light.simpleauth.easyui.NoAuthPIGenerator;
import org.light.simpleauth.verb.AddUser;
import org.light.simpleauth.verb.ChangeMyPasswordUser;
import org.light.simpleauth.verb.ChangePasswordUser;
import org.light.simpleauth.verb.CountSaltUser;
import org.light.simpleauth.verb.FindMyProfileUser;
import org.light.simpleauth.verb.FindUserShadow;
import org.light.simpleauth.verb.LoginUser;
import org.light.simpleauth.verb.LogoutUser;
import org.light.simpleauth.verb.ReadMySession;
import org.light.simpleauth.verb.RegisterUser;
import org.light.simpleauth.verb.UpdateMyProfileUser;
import org.light.simpleauth.verb.UpdateUser;
import org.light.utils.DomainUtil;
import org.light.utils.FieldUtil;
import org.light.utils.PasswordUtil;
import org.light.utils.StringUtil;
import org.light.verb.Activate;
import org.light.verb.ActivateAll;
import org.light.verb.Add;
import org.light.verb.CheckAccess;
import org.light.verb.Clone;
import org.light.verb.CloneAll;
import org.light.verb.Delete;
import org.light.verb.DeleteAll;
import org.light.verb.Export;
import org.light.verb.ExportPDF;
import org.light.verb.FilterExcel;
import org.light.verb.FilterPDF;
import org.light.verb.FindById;
import org.light.verb.FindByName;
import org.light.verb.FindIndexedName;
import org.light.verb.ListActive;
import org.light.verb.ListAll;
import org.light.verb.SearchByFields;
import org.light.verb.SearchByFieldsByPage;
import org.light.verb.SoftDelete;
import org.light.verb.SoftDeleteAll;
import org.light.verb.Toggle;
import org.light.verb.ToggleOne;
import org.light.verb.Update;
public class SimpleAuthModule extends Module{
	protected Domain userDomain;
	protected Domain roleDomain;
	protected Domain privilegeDomain;
	protected Prism loginPrism;
	protected Prism profilePrism;
	protected Prism userPrism;
	protected Prism rolePrism;
	protected Prism privilegePrism;
	protected String generateData = "whennecessary";
	protected Map<String,Boolean> slavesMap = new TreeMap<>();
	
	public SimpleAuthModule() {
		super();
		this.standardName = "SimpleAuth";
	}
	
	public boolean validateDomains() throws ValidateException{
		ValidateInfo info = new ValidateInfo();
		if (userDomain==null||roleDomain==null||privilegeDomain==null) {
			info.addCompileError("所需域对象缺失！");			
		}
		if (userDomain.findFieldByFixedName("userName")==null||!userDomain.findFieldByFixedName("userName").getFieldType().equalsIgnoreCase("String")) {
			info.addCompileError("用户域对象固定名字userName字段设置有问题！");			
		}
		if (userDomain.findFieldByFixedName("password")==null||!userDomain.findFieldByFixedName("password").getFieldType().equalsIgnoreCase("String")
				||(!StringUtil.isBlank(userDomain.findFieldByFixedName("password").getLengthStr())&&Integer.parseInt(userDomain.findFieldByFixedName("password").getLengthStr())<40)){
			info.addCompileError("用户域对象固定名字password字段设置有问题！");			
		}	
		if (userDomain.findFieldByFixedName("salt")==null||!userDomain.findFieldByFixedName("salt").getFieldType().equalsIgnoreCase("String")
				||(!StringUtil.isBlank(userDomain.findFieldByFixedName("salt").getLengthStr())&&Integer.parseInt(userDomain.findFieldByFixedName("salt").getLengthStr())<8)){
			info.addCompileError("用户域对象固定名字salt字段设置有问题！");			
		}	
		if (userDomain.findFieldByFixedName("loginFailure")==null||!(userDomain.findFieldByFixedName("loginFailure").getClassType().getTypeName().equalsIgnoreCase("i32")||userDomain.findFieldByFixedName("loginFailure").getClassType().getTypeName().equalsIgnoreCase("i32")||userDomain.findFieldByFixedName("loginFailure").getClassType().getTypeName().equalsIgnoreCase("i64"))){
			info.addCompileError("用户域对象固定名字loginFailure字段设置有问题！");			
		}	
//		if (roleDomain.findFieldByFixedName("roleName")==null||!roleDomain.findFieldByFixedName("roleName").getFieldType().equalsIgnoreCase("String")) {
//			info.addCompileError("角色域对象roleName字段设置有问题！");			
//		}		
		if (info.success(true))	return true;
		else throw new ValidateException(info);
	}
	
	public boolean validateDataDomains() throws ValidateException{
		ValidateInfo info = new ValidateInfo();
		if (info.success(true))	return true;
		else throw new ValidateException(info);
	}

	@Override
	public void generateModuleFiles(String targetFolderPath, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl) throws Exception {
		this.setPrisms(new ArrayList<>());
		this.addPrism(this.loginPrism);
		this.addPrism(this.userPrism);
		this.addPrism(this.rolePrism);
		this.addPrism(this.privilegePrism);
		this.addPrism(this.profilePrism);
		
		slavesMap.remove(this.userDomain.getStandardName());
		slavesMap.remove(this.roleDomain.getStandardName());
		slavesMap.remove(this.privilegeDomain.getStandardName());
		slavesMap.remove(this.profilePrism.getStandardName());
		
		for (Prism p:this.getPrisms()) {
			setFolderPath(targetFolderPath);
			generatePrismFiles(p,slavesMap,true,genUi, genController,
					genService, genServiceImpl, genDao, genDaoImpl);
		}
		
		LoginMiddlewareGenerator lmwg = new LoginMiddlewareGenerator();
		lmwg.setUserDomain(this.userDomain);
		lmwg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/middleware/"  +lmwg.getFileName(),
				lmwg.generateStatementList().getContent());
		
		MiddlewareModGenerator mmg = new MiddlewareModGenerator();
		writeToFile(targetFolderPath +"src/middleware/"  +mmg.getFileName(),
				mmg.generateStatementList().getContent());
		
		DtoGenerator dg = new DtoGenerator();
		dg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/"+dg.getUserDomain().getDomainSuffix()+"/"  +dg.getFileName(),
				dg.generateStatementList().getContent());
		
		ErrorGenerator eg = new ErrorGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/"+this.userDomain.getDomainSuffix()+"/"  +eg.getFileName(),
				eg.generateStatementList().getContent());
		
		ExtractorsGenerator exg = new ExtractorsGenerator();
		exg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/"+exg.getUserDomain().getDomainSuffix()+"/"  +exg.getFileName(),
				exg.generateStatementList().getContent());
		
		EncryptUtilGenerator ecug = new EncryptUtilGenerator();
		ecug.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/utils/"  +ecug.getFileName(),
				ecug.generateStatementList().getContent());
		
		JwtUtilGenerator jwtg = new JwtUtilGenerator();
		jwtg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/utils/"  +jwtg.getFileName(),
				jwtg.generateStatementList().getContent());
		
		PasswordUtilGenerator pwdg = new PasswordUtilGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/utils/"  +pwdg.getFileName(),
				pwdg.generateStatementList().getContent());
	}
	
	public void generateDummyModuleFiles(String targetFolderPath, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl) throws Exception {
		this.setPrisms(new ArrayList<>());
		this.addPrism(this.loginPrism);
		this.addPrism(this.userPrism);
		this.addPrism(this.rolePrism);
		this.addPrism(this.privilegePrism);
		this.addPrism(this.profilePrism);
		
		slavesMap.remove(this.userDomain.getStandardName());
		slavesMap.remove(this.roleDomain.getStandardName());
		slavesMap.remove(this.privilegeDomain.getStandardName());
		slavesMap.remove(this.profilePrism.getStandardName());
		
		for (Prism p:this.getPrisms()) {
			setFolderPath(targetFolderPath);
			generateDummyPrismFiles(p,slavesMap,true,genUi, genController,
					genService, genServiceImpl, genDao, genDaoImpl);
		}
		
		LoginMiddlewareGenerator lmwg = new LoginMiddlewareGenerator();
		lmwg.setUserDomain(this.userDomain);
		lmwg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/middleware/"  +lmwg.getFileName(),
				lmwg.generateStatementList().getContent());
		
		MiddlewareModGenerator mmg = new MiddlewareModGenerator();
		writeToFile(targetFolderPath +"src/middleware/"  +mmg.getFileName(),
				mmg.generateStatementList().getContent());
		
		DtoGenerator dg = new DtoGenerator();
		dg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/"+dg.getUserDomain().getDomainSuffix()+"/"  +dg.getFileName(),
				dg.generateStatementList().getContent());
		
		ErrorGenerator eg = new ErrorGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/"+this.userDomain.getDomainSuffix()+"/"  +eg.getFileName(),
				eg.generateStatementList().getContent());
		
		ExtractorsGenerator exg = new ExtractorsGenerator();
		exg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/"+exg.getUserDomain().getDomainSuffix()+"/"  +exg.getFileName(),
				exg.generateStatementList().getContent());
		
		EncryptUtilGenerator ecug = new EncryptUtilGenerator();
		ecug.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/utils/"  +ecug.getFileName(),
				ecug.generateStatementList().getContent());
		
		JwtUtilGenerator jwtg = new JwtUtilGenerator();
		jwtg.setUserDomain(this.userDomain);
		writeToFile(targetFolderPath +"src/utils/"  +jwtg.getFileName(),
				jwtg.generateStatementList().getContent());
		
		PasswordUtilGenerator pwdg = new PasswordUtilGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/utils/"  +pwdg.getFileName(),
				pwdg.generateStatementList().getContent());
	}

	@Override
	public void generatePrismsFromDomians() throws Exception {
		if ("MariaDB".equalsIgnoreCase(this.dbType)||"MySQL".equalsIgnoreCase(this.dbType)||"pgsql".equalsIgnoreCase(this.dbType)||"PostgreSQL".equalsIgnoreCase(this.dbType)||"Oracle".equalsIgnoreCase(this.dbType)) {
			ValidateInfo info = new ValidateInfo();
			if (this.userDomain instanceof org.light.domain.Enum) {
				info.addCompileError("用户域对象"+this.userDomain.getStandardName()+"不可以是枚举。");
			}
			if (this.roleDomain instanceof org.light.domain.Enum) {
				info.addCompileError("角色域对象"+this.roleDomain.getStandardName()+"不可以是枚举。");
			}
			if (this.privilegeDomain instanceof org.light.domain.Enum) {
				info.addCompileError("权限域对象"+this.privilegeDomain.getStandardName()+"不可以是枚举。");
			}
			if (this.userDomain.isLegacy()) {
				info.addCompileError("用户域对象"+this.userDomain.getStandardName()+"不可以是遗留域对象。");
			}
			if (this.roleDomain.isLegacy()) {
				info.addCompileError("角色域对象"+this.roleDomain.getStandardName()+"不可以是遗留域对象。");
			}
			if (this.privilegeDomain.isLegacy()) {
				info.addCompileError("权限域对象"+this.privilegeDomain.getStandardName()+"不可以是遗留域对象。");
			}
			if (!info.success(true)) throw new ValidateException(info);
			Prism loginPrism = new Prism();	
			loginPrism.setDomain(this.userDomain);
			loginPrism.setStandardName("LoginPrism");
			loginPrism.setDbType(this.dbType);
			loginPrism.setPackageToken(this.getPackageToken());
			this.loginPrism = loginPrism;
			this.loginPrism.setTitle(this.title);
			this.loginPrism.setSubTitle(this.subTitle);
			this.loginPrism.setFooter(this.footer);
			this.loginPrism.setTechnicalStack(this.technicalstack);
			generateLoginPrismFromUserDomain(true);
			decorateLoginPrism();
			
			Set<Field> deniedFields = new TreeSet<>();
			deniedFields.add(this.userDomain.findFieldByFixedName("password"));
			deniedFields.add(this.userDomain.findFieldByFixedName("salt"));
			deniedFields.add(this.userDomain.findFieldByFixedName("loginFailure"));
			
			Prism profilePrism = new Prism();	
			profilePrism.setDomain(this.userDomain);
			profilePrism.setStandardName("ProfilePrism");
			this.profilePrism = profilePrism;
			this.profilePrism.setTitle(this.title);
			this.profilePrism.setSubTitle(this.subTitle);
			this.profilePrism.setFooter(this.footer);
			this.profilePrism.setTechnicalStack(this.technicalstack);
			generateProfilePrismFromUserDomainWithDeniedFields(true,deniedFields);
			
			Prism userPrism = new Prism();
			userPrism.setDomain(this.userDomain);
			userPrism.setStandardName("UserPrism");
			userPrism.setDbType(this.dbType);
			userPrism.setPackageToken(this.getPackageToken());
			Set<Domain> projectDomains = new TreeSet<>();
			projectDomains.addAll(this.domains);
			userPrism.setProjectDomains(projectDomains);			
			this.userPrism = userPrism;
			
			generateUserPrismFromUserDomainWithDeniedFields(true,deniedFields);

			this.userPrism.setTitle(this.title);
			this.userPrism.setSubTitle(this.subTitle);
			this.userPrism.setFooter(this.footer);
			this.userPrism.setTechnicalStack(this.technicalstack);
			decorateUserPrism();
			
			Prism rolePrism = new Prism();	
			rolePrism.setTitle(this.title);
			rolePrism.setSubTitle(this.subTitle);
			rolePrism.setFooter(this.footer);
			rolePrism.setDomain(this.roleDomain);
			rolePrism.setStandardName("RolePrism");
			rolePrism.setDbType(this.dbType);
			rolePrism.setPackageToken(this.getPackageToken());
			rolePrism.setProjectDomains(projectDomains);
			rolePrism.setTechnicalStack(this.technicalstack);
			rolePrism.generatePrismFromDomain(true);
			
			Prism privilegePrism = new Prism();
			privilegePrism.setTitle(this.title);
			privilegePrism.setSubTitle(this.subTitle);
			privilegePrism.setFooter(this.footer);
			privilegePrism.setDomain(this.privilegeDomain);
			privilegePrism.setStandardName("PrivilegePrism");
			privilegePrism.setDbType(this.dbType);
			privilegePrism.setPackageToken(this.getPackageToken());
			privilegePrism.setProjectDomains(projectDomains);
			privilegePrism.setTechnicalStack(this.technicalstack);
			privilegePrism.generatePrismFromDomain(true);
	
			this.rolePrism = rolePrism;
			this.rolePrism.setTitle(this.title);
			this.rolePrism.setSubTitle(this.subTitle);
			this.rolePrism.setFooter(this.footer);
			this.privilegePrism = privilegePrism;
			this.privilegePrism.setTitle(this.title);
			this.privilegePrism.setSubTitle(this.subTitle);
			this.privilegePrism.setFooter(this.footer);		
			decorateVerbDbType(this.loginPrism,this.dbType);
			decorateVerbDbType(this.userPrism,this.dbType);
			decorateVerbDbType(this.rolePrism,this.dbType);
			decorateVerbDbType(this.privilegePrism,this.dbType);
		}
	}
	
	private void generateProfilePrismFromUserDomainWithDeniedFields(boolean b,Set<Field> deniedFields) throws Exception{
		if (this.userDomain != null) {
			AxumPlainProfileController controller = new AxumPlainProfileController(this.userDomain);
			controller.setPackageToken(this.packageToken);
			controller.setStandardName("Profile"+this.userDomain.getControllerNamingSuffix());
			for (Field f:this.userDomain.getFields()) {
				if (f instanceof Dropdown) {
					controller.addMethod(new ListActive(((Dropdown)f).getTarget()).generateControllerMethod());
				}
			}
			
			this.profilePrism.setAxumController(controller);
			
			Verb changeMyPassword = new ChangeMyPasswordUser(this.userDomain);
			Verb updateProfile = new UpdateMyProfileUser(this.userDomain,deniedFields);
			Verb findProfile = new FindMyProfileUser(this.userDomain,deniedFields);
			this.profilePrism.addVerb(changeMyPassword);
			this.profilePrism.addVerb(updateProfile);
			this.profilePrism.addVerb(findProfile);
			
			for (Verb v : this.profilePrism.getVerbs()) {
				this.profilePrism.getAxumController().addMethod(v.generateControllerMethod());
			}
			
			for (Field f:this.userDomain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					this.profilePrism.getDomianFieldVerbs().add(new AddUploadDomainField(this.userDomain,f));
				}
			}
			
			for (DomainFieldVerb dv : this.profilePrism.getDomianFieldVerbs()) {
				this.profilePrism.getAxumController().addMethod(dv.generateControllerMethod());
			}
			
			EasyUIProfilePI eProfile = new EasyUIProfilePI(this.userDomain);
			eProfile.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eProfile.setNav(this.nav);
			this.profilePrism.addPage(eProfile);	
		}		
	}
	
	public void decrateManyToManyExistsArrMethod(Prism ps) {
		Set<Domain> existsSlaveDomains = new TreeSet<>();
		for (ManyToMany mtm : ps.getManyToManies()) {					
			existsSlaveDomains.add(mtm.getSlave());
			System.out.print("JerryDebug:size:"+existsSlaveDomains.size()+":"+ps.getStandardName());
			for (Domain d:existsSlaveDomains) {
				System.out.print(d.getStandardName()+",");
			}
			System.out.println("");
		}
	}
	
	public void generateLoginPrismFromUserDomain(Boolean ignoreWarning) throws ValidateException, Exception {
		if (this.userDomain != null) {
			AxumPlainLoginController controller = new AxumPlainLoginController(this.userDomain);
			controller.setPackageToken(this.packageToken);
			controller.setStandardName("Login"+this.userDomain.getControllerNamingSuffix());
			controller.setDomain(this.userDomain);
			controller.setUserDomain(this.userDomain);
			controller.setRoleDomain(this.roleDomain);
			controller.setPrivilegeDomain(this.privilegeDomain);
			
			List<Domain> translateDomains = new ArrayList<Domain>();
			for (Field f: this.userDomain.getFields()){
				if (f instanceof Dropdown){
					Dropdown dp = (Dropdown)f;
					Domain target = dp.getTarget();
					if (!target.isLegacy()&&!DomainUtil.inDomainList(target, translateDomains)){
						translateDomains.add(target);
					}
				}
			}
			
			for (Domain d:translateDomains) {
				ListActive list = new ListActive(d);
				controller.addMethod(list.generateControllerMethod());
			}

			this.loginPrism.setAxumController(controller);
			
			ServiceImpl serviceimpl = new ServiceImpl();
			serviceimpl.setDomain(this.userDomain);
			this.loginPrism.setServiceimpl(serviceimpl);
			
			EasyUILoginUserIndexPI eIndex = new EasyUILoginUserIndexPI();
			EasyUIErrorPI eErr = new EasyUIErrorPI();
			EasyUIRegisterUserPI eRegister = new EasyUIRegisterUserPI(this.userDomain,this.roleDomain);
			NoAuthPIGenerator npg = new NoAuthPIGenerator();
			npg.setDomain(this.userDomain);
			npg.setTitle(this.title);
			eIndex.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eIndex.setProjectName(this.getProjectName());
			eErr.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eRegister.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eIndex.setDomain(this.userDomain);
			eErr.setDomain(this.userDomain);
			eIndex.setTechnicalStack(this.technicalstack);
			eErr.setTechnicalStack(this.technicalstack);
			eRegister.setTechnicalStack(this.technicalstack);
			npg.setTechnicalStack(this.technicalstack);
			eRegister.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eRegister.setDomain(this.userDomain);
			this.loginPrism.addPage(eIndex);
			this.loginPrism.addPage(eErr);
			this.loginPrism.addPage(eRegister);		
			this.loginPrism.addPage(npg);	
			
			for (Field f:this.userDomain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					this.loginPrism.getDomianFieldVerbs().add(new AddUploadDomainField(this.userDomain,f));
				}
			}
		}
	}
	
	public void decorateUserPrism() throws Exception{
		Domain user = this.getUserDomain();
		ChangePasswordUser changePassword = new ChangePasswordUser(user,this.dbType);
		FindUserShadow findUserShadow = new FindUserShadow(user,this.dbType);
		CountSaltUser countSalt = new CountSaltUser(user,this.dbType);
		RegisterUser register = new RegisterUser(user,this.getRoleDomain(),this.dbType);
		LoginUser loginUser = new LoginUser(user);
		LogoutUser logoutUser = new LogoutUser(user);
		
		Set<Verb> verbs = new TreeSet<Verb>();
		verbs.add(changePassword);
		verbs.add(findUserShadow);
		verbs.add(countSalt);
		verbs.add(register);
		verbs.add(loginUser);
		verbs.add(logoutUser);
		decorateVerbsInUserPrism(verbs);
	}
	
	public void decorateLoginPrism() throws Exception{
		Domain user = this.getUserDomain();
		RegisterUser registerUser = new RegisterUser(user,this.roleDomain,this.dbType);
		LoginUser loginUser = new LoginUser(user);
		LogoutUser logoutUser = new LogoutUser(user);
		//ChangePasswordUser changePassword = new ChangePasswordUser(user);
		FindUserShadow getPasswordUser = new FindUserShadow(user,this.dbType);
		ReadMySession readMySession = new ReadMySession(user);
		readMySession.setRoleDomain(this.roleDomain);
		readMySession.setPrivilegeDomain(this.privilegeDomain);
		Set<Verb> verbs = new TreeSet<Verb>();
		verbs.add(registerUser);
		verbs.add(loginUser);
		verbs.add(logoutUser);
		//verbs.add(changePassword);
		verbs.add(getPasswordUser);
		verbs.add(readMySession);
		decorateVerbsInLoginPrism(verbs);
	}
	
	public void decorateVerbsInUserPrism(Set<Verb> verbs) throws Exception{
		Set<Field> deniedFields = new TreeSet<>();
		for (Field f:this.userDomain.getFields()) {
			if ("password".equals(f.getFixedName())||"salt".equals(f.getFixedName())||"loginFailure".equals(f.getFixedName())) {
				deniedFields.add(f);
			}
		}
		
		Domain domain = this.getUserDomain();
		ServiceImpl serviceimpl = this.userPrism.getServiceImpl();
		DaoImpl daoimpl = this.userPrism.getDaoImpl();
		DummyDaoImpl dummydaoimpl = this.userPrism.getDummydaoimpl();
		Controller controller = this.userPrism.getAxumController();
		for (Verb v : verbs) {
			v.setDeniedFields(deniedFields);
			this.userPrism.addVerb(v);
			v.setDomain(domain);
			if (! (v instanceof LoginUser)) {
				serviceimpl.addMethod(v.generateServiceImplMethod());
			}
			daoimpl.addMethod(v.generateDaoImplMethod());
			dummydaoimpl.addMethod(v.generateDummyDaoImplMethod());
			if (v.getVerbName().equalsIgnoreCase("ChangePassword"+this.userDomain.getCapFirstDomainName())) {
				controller.addMethod(v.generateControllerMethod());
			}
		}		
		
		this.userPrism.setPages(new TreeSet<PrismInterface>());
		EasyUIUserPagePI eUser = new EasyUIUserPagePI(this.userDomain,this.roleDomain,this.technicalstack,this.dbType);
		eUser.setTitles(this.title, this.subTitle, this.footer);
		
		List<Domain> allDomainList = new ArrayList<>();
		allDomainList.add(this.userDomain);
		allDomainList.add(this.roleDomain);
		allDomainList.add(this.privilegeDomain);
		this.userPrism.addPage(eUser);
	}	
	
	public void decorateVerbsInUserOraclePrism(Set<Verb> verbs) throws Exception{
		Set<Verb> removeVerbs = new TreeSet<>();
		Update update = new Update(this.userDomain);
		Add add = new Add(this.userDomain);
		
		Export ep = new Export(this.userDomain);
		
		removeVerbs.add(add);
		removeVerbs.add(update);
		
		for (Verb v2:removeVerbs) {
			this.userPrism.removeVerb(v2);				
		}		
		Domain domain = this.getUserDomain();
		ServiceImpl serviceimpl = this.userPrism.getServiceImpl();
		DaoImpl daoimpl = this.userPrism.getDaoImpl();
		Controller controller = this.userPrism.getAxumController();
		for (Verb v : verbs) {
			this.userPrism.addVerb(v);
			v.setDomain(domain);
			serviceimpl.addMethod(v.generateServiceImplMethod());
			daoimpl.addMethod(v.generateDaoImplMethod());
			if (v.getVerbName().equals("ChangePassword"+this.userDomain.getCapFirstDomainName())) {
				controller.addMethod(v.generateControllerMethod());
			}
		}
		
		Set<Field> deniedFields = new TreeSet<>();
		for (Field f:this.userDomain.getFields()) {
			if ("password".equals(f.getFixedName())||"salt".equals(f.getFixedName())||"loginFailure".equals(f.getFixedName())) {
				deniedFields.add(f);
			}
		}
		
		AddUser addUser = new AddUser(this.userDomain, this.roleDomain);
		addUser.setDbType(this.dbType);
			
		Update updateUser = new Update(this.userDomain);
		updateUser.setDbType(this.dbType);
		updateUser.setDeniedFields(deniedFields);
		Set<Verb> replacedVerbs = new TreeSet<>();
		replacedVerbs.add(addUser);
		replacedVerbs.add(updateUser);
		
		Export eeff = new Export(this.userDomain);
		
		eeff.setDeniedFields(deniedFields);
		Set<Verb> exVerbs = new TreeSet<>();
		
		exVerbs.add(eeff);
		for (Verb v : exVerbs) {
			this.userPrism.addVerb(v);
			v.setDomain(domain);
//			service.addMethod(v.generateServiceMethodDefinition());
//			serviceimpl.addMethod(v.generateServiceImplMethod());
//			dao.addMethod(v.generateDaoMethodDefinition());
//			daoimpl.addMethod(v.generateDaoImplMethod());
//			mdecorater.addDaoXmlMethod(v.generateDaoImplMethod());
			controller.addMethod(v.generateControllerMethod());
		}
		
		for (Verb v :replacedVerbs) {
			serviceimpl.addMethod(v.generateServiceImplMethod());
			daoimpl.addMethod(v.generateDaoImplMethod());
			controller.addMethod(v.generateControllerMethod());
		}

		this.userPrism.setPages(new TreeSet<PrismInterface>());
		EasyUIUserPagePI eUser = new EasyUIUserPagePI(this.userDomain,this.roleDomain,this.technicalstack,this.dbType);
		eUser.setTitles(this.title, this.subTitle, this.footer);
		
		List<Domain> allDomainList = new ArrayList<>();
		allDomainList.add(this.userDomain);
		allDomainList.add(this.roleDomain);
		allDomainList.add(this.privilegeDomain);
		this.userPrism.addPage(eUser);
	}	
	
	public void decorateVerbsInLoginPrism(Set<Verb> verbs) throws Exception{
		Domain domain = this.getUserDomain();
		Controller controller = this.loginPrism.getAxumController();
		ServiceImpl serviceimpl = this.loginPrism.getServiceImpl();
		for (Verb v : verbs) {
			this.loginPrism.addVerb(v);
			v.setDomain(domain);
			//service.addMethod(v.generateServiceMethodDefinition());
			if (v instanceof LoginUser) {
				serviceimpl.addMethod(v.generateServiceImplMethod());
			}
			//dao.addMethod(v.generateDaoMethodDefinition());
			//daoimpl.addMethod(v.generateDaoImplMethod());
			controller.addMethod(v.generateControllerMethod());
		}
		for (DomainFieldVerb dfv:this.loginPrism.getDomianFieldVerbs()) {
			controller.addMethod(dfv.generateControllerMethod());
		}
	}

	public Domain getUserDomain() {
		return userDomain;
	}

	public void setUserDomain(Domain userDomain) {
		this.userDomain = userDomain;
	}

	public Domain getRoleDomain() {
		return roleDomain;
	}

	public void setRoleDomain(Domain roleDomain) {
		this.roleDomain = roleDomain;
	}

	public Domain getPrivilegeDomain() {
		return privilegeDomain;
	}

	public void setPrivilegeDomain(Domain privilegeDomain) {
		this.privilegeDomain = privilegeDomain;
	}

	public Prism getUserPrism() {
		return userPrism;
	}

	public void setUserPrism(Prism userPrism) {
		this.userPrism = userPrism;
	}

	public Prism getRolePrism() {
		return rolePrism;
	}

	public void setRolePrism(Prism rolePrism) {
		this.rolePrism = rolePrism;
	}

	public Prism getPrivilegePrism() {
		return privilegePrism;
	}

	public Prism getLoginPrism() {
		return loginPrism;
	}

	public void setPrivilegePrism(Prism privilegePrism) {
		this.privilegePrism = privilegePrism;
	}

	public void setLoginPrism(Prism loginPrism) {
		this.loginPrism = loginPrism;
	}
	
	public static String packagetokenToFolder(String packageToken) {
		String folder = packageToken.replace('.', '/');
		folder += "/";
		return folder;
	}
	
	public static String folderToPackageToken(String folder) {
		String packagetoken = folder.replace('/', '.');
		if (packagetoken.charAt(packagetoken.length() - 1) == '.')
			packagetoken = packagetoken.substring(0, packagetoken.length() - 1);
		return packagetoken;
	}
	
	public void writeToFile(String filePath, String content) throws Exception {
		File f = new File(filePath);
		if (!f.getParentFile().exists()) {
			f.getParentFile().mkdirs();
		}
		f.createNewFile();
		try (Writer fw = new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream(f.getAbsolutePath()), "UTF-8"))) {
			fw.write(content, 0, content.length());
		}
	}
	
	public void generatePrismFiles(Prism prism,Map<String,Boolean> slavesMap,Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		ValidateInfo info = prism.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String srcfolderPath = folderPath ;
			srcfolderPath = folderPath + "src/"+packagetokenToFolder(this.packageToken);

			writeToFile(srcfolderPath +packagetokenToFolder(prism.getDomain().getDomainSuffix())  +prism.getDomain().getSnakeDomainNameWithSuffix()+ ".rs",
					prism.getDomain().generateClassStatementList().getContent());
			
			if (genDaoImpl&&prism.getDaoImpl() != null) {
				writeToFile(
						srcfolderPath + packagetokenToFolder(prism.getDomain().getDaoimplSuffix()) +  prism.getDomain().getSnakeDomainName() + "_dao.rs",
						prism.getDaoimpl().generateDaoImplString());
			}

			if (genServiceImpl&&prism.getServiceImpl() != null) {
				writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getServiceimplSuffix()) + prism.getDomain().getSnakeDomainName()
						+ "_service.rs", prism.getServiceImpl().generateServiceImplString());
			}

			if (genController&&prism.getAxumController() != null) {
				writeToFile(srcfolderPath +  packagetokenToFolder(prism.getDomain().getControllerSuffix()) 
						+ StringUtil.getSnakeName(prism.getAxumController().getStandardName())+".rs", prism.getAxumController().generateControllerString());
			}

			if (genUi) {
				for (PrismInterface page : prism.getPages()) {
					page.generatePIFiles(folderPath);
				}
				for (ManyToMany mtm : prism.getManyToManies()) {
					EasyUIMtmPI mpage =  mtm.getEuPI();
					mpage.setTechnicalStack(this.technicalstack);
					mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
					mpage.setNav(this.getNav());
					mpage.generatePIFiles(folderPath);
				}
				
				AuthJsGenerator aug = new AuthJsGenerator(this.userDomain);					
				writeToFile(folderPath + "template/js/auth.js",aug.generateUtilString());
			
				if ("tower".equalsIgnoreCase(this.getTechnicalstack())) {
					EasyUIErrorPI eErr0 = new EasyUIErrorPI();
					eErr0.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
					eErr0.setDomain(this.userDomain);
				
					writeToFile(folderPath + "template/error/4xx.html",
							eErr0.generateStatementList().getContent());
					writeToFile(folderPath + "template/error/5xx.html",
							eErr0.generateStatementList().getContent());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	
	
	public void generateDummyPrismFiles(Prism prism,Map<String,Boolean> slavesMap,Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		ValidateInfo info = prism.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String srcfolderPath = folderPath ;
			srcfolderPath = folderPath + "src/"+packagetokenToFolder(this.packageToken);

			writeToFile(srcfolderPath +packagetokenToFolder(prism.getDomain().getDomainSuffix())  +prism.getDomain().getSnakeDomainNameWithSuffix()+ ".rs",
					prism.getDomain().generateClassStatementList().getContent());
			
			if (genDaoImpl&&prism.getDummydaoimpl() != null) {
				writeToFile(
						srcfolderPath + packagetokenToFolder(prism.getDomain().getDaoimplSuffix()) +  prism.getDomain().getSnakeDomainName() + "_dummydao.rs",
						prism.getDummydaoimpl().generateDaoImplString());
			}

			if (genServiceImpl&&prism.getServiceImpl() != null) {
				writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getServiceimplSuffix()) + prism.getDomain().getSnakeDomainName()
						+ "_service.rs", prism.getServiceImpl().generateServiceImplString());
			}

			if (genController&&prism.getAxumController() != null) {
				writeToFile(srcfolderPath +  packagetokenToFolder(prism.getDomain().getControllerSuffix()) 
						+ StringUtil.getSnakeName(prism.getAxumController().getStandardName())+".rs", prism.getAxumController().generateControllerString());
			}

			if (genUi) {
				for (PrismInterface page : prism.getPages()) {
					page.generatePIFiles(folderPath);
				}
				for (ManyToMany mtm : prism.getManyToManies()) {
					EasyUIMtmPI mpage =  mtm.getEuPI();
					mpage.setTechnicalStack(this.technicalstack);
					mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
					mpage.setNav(this.getNav());
					mpage.generatePIFiles(folderPath);
				}
				
				AuthJsGenerator aug = new AuthJsGenerator(this.userDomain);					
				writeToFile(folderPath + "template/js/auth.js",aug.generateUtilString());
			
				if ("tower".equalsIgnoreCase(this.getTechnicalstack())) {
					EasyUIErrorPI eErr0 = new EasyUIErrorPI();
					eErr0.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
					eErr0.setDomain(this.userDomain);
				
					writeToFile(folderPath + "template/error/4xx.html",
							eErr0.generateStatementList().getContent());
					writeToFile(folderPath + "template/error/5xx.html",
							eErr0.generateStatementList().getContent());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	

	public String getGenerateData() {
		return generateData;
	}

	public void setGenerateData(String generateData) {
		this.generateData = generateData;
	}
	
	public List<List<Domain>> genData() throws Exception{
		List<List<Domain>> results = new ArrayList<>();
		results.add(genUserData());
		results.add(genRoleData());
		return results;
		
	}
	
	public List<Domain> genRoleData() throws Exception{
		List<Domain> roles = new ArrayList<>();
		Domain role0 = (Domain)this.roleDomain.deepClone();
		role0.getDomainId().setFieldValue("1");
		role0.getDomainName().setFieldValue("admin");
		role0.getActive().setFieldValue(role0.getDomainActiveStr());
		
		Domain role1 = (Domain)this.roleDomain.deepClone();
		role1.getDomainId().setFieldValue("2");
		role1.getDomainName().setFieldValue("user");
		role1.getActive().setFieldValue(role0.getDomainActiveStr());
		
		roles.add(role0);
		roles.add(role1);
		return roles;
	}
	
	public List<Domain> genUserData() throws Exception{
		List<Domain> users = new ArrayList<>();
		Domain user0 = (Domain)this.userDomain.deepClone();
		user0.getDomainId().setFieldValue("1");
		user0.getDomainName().setFieldValue("admin");
		user0.getActive().setFieldValue(user0.getDomainActiveStr());
		user0.findFieldByFixedName("userName").setFieldValue("admin");
		//user0.findFieldByFixedName("salt").setFieldValue(enc0[0]);
		//user0.findFieldByFixedName("password").setFieldValue(enc0[1]);
		user0.findFieldByFixedName("loginFailure").setFieldValue("0");
		
		Domain user1 = (Domain)this.userDomain.deepClone();
		user1.getDomainId().setFieldValue("2");
		user1.getDomainName().setFieldValue("jerry");
		user1.getActive().setFieldValue(user0.getDomainActiveStr());
		user1.findFieldByFixedName("userName").setFieldValue("jerry");
		//user1.findFieldByFixedName("salt").setFieldValue(enc1[0]);
		//user1.findFieldByFixedName("password").setFieldValue(enc1[1]);
		user1.findFieldByFixedName("loginFailure").setFieldValue("0");
		
		users.add(user0);
		users.add(user1);
		return users;
	}

	public void decorateVerbDbType(Prism prism,String dbType) {
		for (Verb v:prism.getVerbs()) {
			v.setDbType(dbType);
		}
		for (NoControllerVerb nv:prism.getNoControllerVerbs()) {
			nv.setDbType(dbType);
		}
	}
	
	public List<List<Domain>> decorateDataDomains(List<List<Domain>> dataDomains) throws Exception{
		dataDomains = DomainUtil.removeDataDomainsFromLists(dataDomains,this.privilegeDomain.getStandardName());
		long serial = 1L;
		List<Domain> myPrivs = new ArrayList<>();
		Set<Domain> authDomains = new TreeSet<>();
		authDomains.add(this.userDomain);
		authDomains.add(this.roleDomain);
		authDomains.add(this.privilegeDomain);
		
		Set<Domain> privDomains = this.nav.getDomains();
		for (Domain d: privDomains) {
			if (!DomainUtil.inDomainSet(d, authDomains)) {
				Domain priv = (Domain)this.privilegeDomain.deepClone();
				
				for (Field f:priv.getFields()) {
					if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
				
				priv.getDomainId().setFieldValue(""+serial++);
				priv.getDomainName().setFieldValue(d.getStandardName());
				priv.getActive().setFieldValue(this.privilegeDomain.getDomainActiveStr());
				myPrivs.add(priv);
			}
		}
		this.privilegeDomain.setDummyDb(myPrivs);
		dataDomains.add(myPrivs);
		
		boolean isAdminRoleExists = false;
		boolean isUserRoleExists = false;
		List<Domain> myRoles = new ArrayList<>();
		for (List<Domain> datas : dataDomains) {
			for (Domain d : datas) {
				for (Field f:d.getFields()) {
					if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
				
				if (d.getStandardName().equals(this.roleDomain.getStandardName())) {
					myRoles.add(d);
					if (d.getDomainName().getFieldValue().equals("admin")) {
						isAdminRoleExists = true;
						String privsstr = "";
						for (Domain priv : myPrivs) {
							privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
						}
						if (privsstr.endsWith(","))
							privsstr = privsstr.substring(0, privsstr.length() - 1);
						for (ManyToMany mtm : d.getManyToManies()) {
							mtm.setMaster(d);
							mtm.setValues(privsstr);
						}
					}
				}
				if (d.getStandardName().equals(this.roleDomain.getStandardName()) && d.getDomainName().getFieldValue().equals("user")) {
					isUserRoleExists = true;
					String privsstr = "";
					for (Domain priv : myPrivs) {
						privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
					}
					if (privsstr.endsWith(","))
						privsstr = privsstr.substring(0, privsstr.length() - 1);
					for (ManyToMany mtm : d.getManyToManies()) {
						mtm.setMaster(d);
						mtm.setValues(privsstr);
					}
				}
			}
		}
		if (!isAdminRoleExists) {
			Domain adminRole = (Domain)this.roleDomain.deepClone();
			
			for (Field f:adminRole.getFields()) {
				if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
			}
			
			adminRole.getDomainId().setFieldValue("9000");
			adminRole.getDomainName().setFieldValue("admin");
			adminRole.getActive().setFieldValue(adminRole.getDomainActiveStr());
			String privsstr = "";
			for (Domain priv : myPrivs) {
				privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
			}
			if (privsstr.endsWith(","))
				privsstr = privsstr.substring(0, privsstr.length() - 1);
			for (ManyToMany mtm : adminRole.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.privilegeDomain.getStandardName())) {
					mtm.setMasterValue(adminRole.getDomainId().getFieldValue());
					mtm.setMaster(adminRole);
					mtm.setValues(privsstr);
				}
			}
			myRoles.add(adminRole);
		}
		if (!isUserRoleExists) {
			Domain userRole = (Domain)this.roleDomain.deepClone();
			
			for (Field f:userRole.getFields()) {
				if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
			}
			
			userRole.getDomainId().setFieldValue("9001");
			userRole.getDomainName().setFieldValue("user");
			userRole.getActive().setFieldValue(userRole.getDomainActiveStr());
			
			String privsstr = "";
			for (Domain priv : myPrivs) {
				privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
			}
			if (privsstr.endsWith(","))
				privsstr = privsstr.substring(0, privsstr.length() - 1);
			for (ManyToMany mtm : userRole.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.privilegeDomain.getStandardName())) {
					mtm.setMasterValue(userRole.getDomainId().getFieldValue());
					mtm.setMaster(userRole);
					mtm.setValues(privsstr);
				}
			}
			
			myRoles.add(userRole);
		}
		dataDomains = DomainUtil.removeDataDomainsFromLists(dataDomains,this.roleDomain.getStandardName());
		dataDomains.add(myRoles);
		this.roleDomain.setDummyDb(myRoles);
		
		boolean isAdminExists = false;
		boolean isJerryExists = false;
		List<Domain> myUsers = new ArrayList<>();
		List<String> salts = new ArrayList<>();
		for (List<Domain> datas:dataDomains) {
			for (Domain d : datas)
			{		
				if (d.getStandardName().equals(this.userDomain.getStandardName())) {
					for (Field f:d.getFields()) {
						if (f instanceof Dropdown && (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue()))) {
							f.setFieldValue("-1");
						} else if (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue())) {
							f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
						}
					}
					
					String password = d.findFieldByFixedName("password").getFieldValue();
					String salt = PasswordUtil.generateSalt(salts);
					password = PasswordUtil.getPassword(password, salt);
					salts.add(salt);

					d.findFieldByFixedName("password").setFieldValue(password);
					d.findFieldByFixedName("salt").setFieldValue(salt);
					d.findFieldByFixedName("loginFailure").setFieldValue("0");
					myUsers.add(d);
					if (d.getDomainName().getFieldValue().equals("admin")) {
						isAdminExists = true;
						for (ManyToMany mtm : d.getManyToManies()) {
							Domain adminRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "admin");
							if (adminRole != null) {
								String fieldValue = mtm.getValues();
								if (!StringUtil.isBlank(fieldValue)) fieldValue = fieldValue + ","+adminRole.getDomainId().getFieldValue();
								else fieldValue = adminRole.getDomainId().getFieldValue();
								mtm.setMaster(d);
								mtm.setValues(fieldValue);
							}
						}
					}
					if (d.getDomainName().getFieldValue().equals("jerry")) {
						isJerryExists = true;
						for (ManyToMany mtm : d.getManyToManies()) {
							Domain adminRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "user");
							if (adminRole != null) {
								String fieldValue = mtm.getValues();
								if (!StringUtil.isBlank(fieldValue)) fieldValue = fieldValue + ","+adminRole.getDomainId().getFieldValue();
								else fieldValue = adminRole.getDomainId().getFieldValue();
								mtm.setMaster(d);
								mtm.setValues(fieldValue);
							}
						}
					}
				}
			}
		}
		if (!isAdminExists) {
			Domain admin = (Domain)this.userDomain.deepClone();
			
			for (Field f:admin.getFields()) {
				if (f instanceof Dropdown && (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue()))) {
					f.setFieldValue("-1");
				} else if (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue())) {
					f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
			}
			
			admin.getDomainId().setFieldValue("9000");
			admin.getDomainName().setFieldValue("admin");
			admin.getActive().setFieldValue(admin.getDomainActiveStr());
			
			String password = "admin";
			String salt = PasswordUtil.generateSalt(salts);
			password = PasswordUtil.getPassword(password, salt);
			salts.add(salt);
			admin.findFieldByFixedName("password").setFieldValue(password);
			admin.findFieldByFixedName("salt").setFieldValue(salt);
			admin.findFieldByFixedName("loginFailure").setFieldValue("0");
			
			for (ManyToMany mtm : admin.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.roleDomain.getStandardName())) {
					Domain adminRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "admin");
					if (adminRole != null) {
						String fieldValue = adminRole.getDomainId().getFieldValue();
						mtm.setMasterValue(admin.getDomainId().getFieldValue());
						mtm.setMaster(admin);
						mtm.setValues(fieldValue);
					}
				}
			}
			myUsers.add(admin);
		}
		if (!isJerryExists) {
			Domain jerry = (Domain)this.userDomain.deepClone();
			
			for (Field f:jerry.getFields()) {
				if (f instanceof Dropdown && (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue()))) {
					f.setFieldValue("-1");
				} else if (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue())) {
					f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
			}
			
			jerry.getDomainId().setFieldValue("9001");
			jerry.getDomainName().setFieldValue("jerry");
			jerry.getActive().setFieldValue(jerry.getDomainActiveStr());
			
			String password = "jerry";
			String salt = PasswordUtil.generateSalt(salts);
			password = PasswordUtil.getPassword(password, salt);
			salts.add(salt);
			jerry.findFieldByFixedName("password").setFieldValue(password);
			jerry.findFieldByFixedName("salt").setFieldValue(salt);
			jerry.findFieldByFixedName("loginFailure").setFieldValue("0");
			
			for (ManyToMany mtm : jerry.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.roleDomain.getStandardName())) {
					Domain userRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "user");
					if (userRole != null) {
						String fieldValue = userRole.getDomainId().getFieldValue();
						mtm.setMasterValue(jerry.getDomainId().getFieldValue());
						mtm.setMaster(jerry);
						mtm.setValues(fieldValue);
					}
				}
			}
			myUsers.add(jerry);
		}
		dataDomains = DomainUtil.removeDataDomainsFromLists(dataDomains,this.userDomain.getStandardName());
		dataDomains.add(myUsers);
		this.userDomain.setDummyDb(myUsers);
		return dataDomains;
	}
	
	@Override
	public void setNav(Nav nav) {
		super.setNav(nav);
		if (this.userPrism!=null) {
			for (PrismInterface page:this.userPrism.getPages()) {
				page.setNav(nav);
			}
		}
		if (this.rolePrism!=null) {
			for (PrismInterface page:this.rolePrism.getPages()) {
				page.setNav(nav);
			}
		}
		if (this.privilegePrism!=null) {
			for (PrismInterface page:this.privilegePrism.getPages()) {
				page.setNav(nav);
			}
		}
		for (PrismInterface page:this.profilePrism.getPages()) {
			page.setNav(nav);
		}
	}
	
	@Override
	public Nav getNav() {
		return super.getNav();
	}
	
	public void generateUserPrismFromUserDomainWithDeniedFields(Boolean ignoreWarning,Set<Field> deniedFields) throws ValidateException, Exception {
		if (this.userDomain != null) {
			if (this.getPackageToken() != null) {
				this.userDomain.setPackageToken(packageToken);
			}
			
			this.userDomain.decorateCompareTo();

			DaoImpl daoimpl = new DaoImpl();
			daoimpl.setPackageToken(this.userDomain.getPackageToken());
			daoimpl.setDomain(this.userDomain);
			this.userPrism.setDaoImpl(daoimpl);
			
			DummyDaoImpl dummydaoimpl = new DummyDaoImpl();
			dummydaoimpl.setPackageToken(this.userDomain.getPackageToken());
			dummydaoimpl.setDomain(this.userDomain);
			this.userPrism.setDummydaoimpl(dummydaoimpl);
			
			ServiceImpl serviceimpl = new ServiceImpl(this.userDomain);
			serviceimpl.setPackageToken(this.userDomain.getPackageToken());
			serviceimpl.setDomain(this.userDomain);
			this.userPrism.setServiceImpl(serviceimpl);

			ListAll listAll = new ListAll(this.userDomain);	
			listAll.setDeniedFields(deniedFields);
			listAll.setDbType(this.dbType);
			Verb update = this.userDomain.hasDomainId() ?new UpdateUser(this.userDomain):null;
			Verb delete = this.userDomain.hasDomainId() ?new Delete(this.userDomain):null;
			AddUser add = this.userDomain.hasDomainId() ?new AddUser(this.userDomain,this.roleDomain):null;
			//add.setDeniedFields(deniedFields);
			add.setDbType(this.dbType);
			Verb softdelete = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new SoftDelete(this.userDomain):null;
			FindById findbyid = this.userDomain.hasDomainId() ? new FindById(this.userDomain):null;
			findbyid.setDeniedFields(deniedFields);
			findbyid.setDbType(this.dbType);
			FindByName findbyname = this.userDomain.hasDomainName() ? new FindByName(this.userDomain):null;
			findbyname.setDeniedFields(deniedFields);
			findbyname.setDbType(this.dbType);
			ListActive listactive = this.userDomain.hasActiveField()?new ListActive(this.userDomain):null;
			listactive.setDeniedFields(deniedFields);
			listactive.setDbType(this.dbType);
			Verb deleteAll = this.userDomain.hasDomainId() ?new DeleteAll(this.userDomain):null;
			Verb softDeleteAll = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new SoftDeleteAll(this.userDomain):null;
			Verb toggle = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new Toggle(this.userDomain):null;
			Verb toggleOne = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new ToggleOne(this.userDomain):null;
			SearchByFieldsByPage searchByFieldsByPage = new SearchByFieldsByPage(this.userDomain);
			searchByFieldsByPage.setDeniedFields(deniedFields);
			searchByFieldsByPage.setDbType(this.dbType);
			Verb activate = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new Activate(this.userDomain):null;
			Verb activateAll = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new ActivateAll(this.userDomain):null;
			Verb export = new Export(this.userDomain);
			export.setDeniedFields(deniedFields);
			Verb exportPDF = new ExportPDF(this.userDomain);
			exportPDF.setDeniedFields(deniedFields);
			
			SearchByFields searchByFields = new SearchByFields(this.userDomain);
			searchByFields.setDeniedFields(deniedFields);
			searchByFields.setDbType(this.dbType);
			Verb filterExcel = new FilterExcel(this.userDomain);
			filterExcel.setDeniedFields(deniedFields);
			Verb filterPDF = new FilterPDF(this.userDomain);
			filterPDF.setDeniedFields(deniedFields);
			
			Verb clone	= this.userDomain.hasDomainId() ?new Clone(this.userDomain):null;
			Verb findIndexedName= this.userDomain.hasDomainId() ?new FindIndexedName(this.userDomain):null;
			Verb cloneAll = this.userDomain.hasDomainId()  ?new CloneAll(this.userDomain):null;
			Verb checkAccess = new CheckAccess(this.userDomain);
			
			CountAllPage countAllPage = new CountAllPage(this.userDomain);
			CountSearchByFieldsRecords countSearchByFieldsRecords = new CountSearchByFieldsRecords(this.userDomain);
			countSearchByFieldsRecords.setDeniedFields(deniedFields);
			countSearchByFieldsRecords.setDbType(this.dbType);
			CountActiveRecords countActiveRecords = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ? new CountActiveRecords(this.userDomain):null;

			for (Field f:this.userDomain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					this.userPrism.addDomianFieldVerb(new AddUploadDomainField(this.userDomain,f));
				}
			}
			this.userPrism.addVerb(listAll);
			this.userPrism.addVerb(update);
			this.userPrism.addVerb(delete);
			this.userPrism.addVerb(add);
			this.userPrism.addVerb(softdelete);
			this.userPrism.addVerb(findbyid);
			this.userPrism.addVerb(findbyname);
			this.userPrism.addVerb(listactive);
			this.userPrism.addVerb(deleteAll);
			this.userPrism.addVerb(softDeleteAll);
			this.userPrism.addVerb(toggle);
			this.userPrism.addVerb(toggleOne);
			this.userPrism.addVerb(searchByFieldsByPage);
			this.userPrism.addVerb(activate);
			this.userPrism.addVerb(activateAll);
			this.userPrism.addVerb(export);
			this.userPrism.addVerb(exportPDF);
			this.userPrism.addVerb(searchByFields);
			this.userPrism.addVerb(filterExcel);
			this.userPrism.addVerb(filterPDF);
			this.userPrism.addVerb(clone);
			this.userPrism.addVerb(findIndexedName);
			this.userPrism.addVerb(cloneAll);
			this.userPrism.addVerb(checkAccess);

			if (countAllPage !=null) this.userPrism.addNoControllerVerb(countAllPage);
			if (countSearchByFieldsRecords !=null) this.userPrism.addNoControllerVerb(countSearchByFieldsRecords);
			if (countActiveRecords !=null) this.userPrism.addNoControllerVerb(countActiveRecords);
			this.userPrism.setAxumController(new AxumController(this.userPrism.getVerbs(), this.userDomain,ignoreWarning,this.userPrism.getManyToManies()));
			this.userPrism.getAxumController().setPackageToken(this.packageToken);

			for (Verb v : this.userPrism.getVerbs()) {
				v.setDomain(userDomain);
				v.setDbType(this.dbType);
				serviceimpl.addMethod(v.generateServiceImplMethod());
				daoimpl.addMethod(v.generateDaoImplMethod());
				dummydaoimpl.addMethod(v.generateDummyDaoImplMethod());
				this.userPrism.getAxumController().addMethod(v.generateControllerMethod());
			}

			for (NoControllerVerb nVerb : this.userPrism.getNoControllerVerbs()) {
				nVerb.setDomain(userDomain);
				if (! (nVerb instanceof CountActiveRecords)) {
					serviceimpl.addMethod(nVerb.generateServiceImplMethod());
				}
				daoimpl.addMethod(nVerb.generateDaoImplMethod());
				dummydaoimpl.addMethod(nVerb.generateDummyDaoImplMethod());
			}

			for (DaoOnlyVerb oVerb : this.userPrism.getDaoOnlyVerbs()) {
				oVerb.setDomain(userDomain);
				daoimpl.addMethod(oVerb.generateDaoImplMethod());
				dummydaoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
			}
			
			for (DomainFieldVerb dfv:this.userPrism.getDomianFieldVerbs()) {
				this.userPrism.getAxumController().addMethod(dfv.generateControllerMethod());
			}

			EasyUIGridPagePI easyui = new EasyUIGridPagePI(this.userDomain);
			easyui.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			easyui.setDomain(this.userDomain);
			easyui.setTechnicalStack(this.technicalstack);
			this.userPrism.addPage(easyui);

			if (this.userDomain.getManyToManies() != null && this.userDomain.getManyToManies().size() > 0) {
				for (ManyToMany mtm : this.userDomain.getManyToManies()) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.userDomain.getStandardName();
					if (DomainUtil.setContainsDomain(this.userPrism.getProjectDomains(), masterName)
							&& DomainUtil.setContainsDomain(this.userPrism.getProjectDomains(), slaveName)) {
						Domain tempo = DomainUtil.lookupDoaminInSet(this.userPrism.getProjectDomains(), slaveName);
						Domain myslave = tempo==null?null:(Domain)tempo.deepClone();
						if (myslave == null) continue;
						myslave.setAlias(myslave.getCapFirstDomainName());
						myslave.setAliasLabel(myslave.getText());
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						ManyToMany mymtm = new ManyToMany(DomainUtil.lookupDoaminInSet(this.userPrism.getProjectDomains(), masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						mymtm.setSlaveAliasLabel(mtm.getSlaveAliasLabel());
						mymtm.setValues(mtm.getValues());
						this.userPrism.getManyToManies().add(mymtm);
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.userPrism.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.userPrism.getManyToManies()) {
				mtm.setTitle(this.title);
				mtm.setSubTitle(this.subTitle);
				mtm.setFooter(this.footer);
				mtm.setCrossOrigin(this.crossOrigin);
				this.userPrism.getServiceimpl().addMethod(mtm.getAssign().generateServiceImplMethod());
				this.userPrism.getDaoimpl().addMethod(mtm.getAssign().generateDaoImplMethod());
				this.userPrism.getDummydaoimpl().addMethod(mtm.getAssign().generateDummyDaoImplMethod());
				this.userPrism.getAxumController().addMethod(mtm.getAssign().generateControllerMethod());
				this.userPrism.getAxumController().addTwoDomainVerb(mtm.getAssign());
				
				this.userPrism.getServiceimpl().addMethod(mtm.getRevoke().generateServiceImplMethod());
				this.userPrism.getDaoimpl().addMethod(mtm.getRevoke().generateDaoImplMethod());
				this.userPrism.getDummydaoimpl().addMethod(mtm.getRevoke().generateDummyDaoImplMethod());
				this.userPrism.getAxumController().addMethod(mtm.getRevoke().generateControllerMethod());
				this.userPrism.getAxumController().addTwoDomainVerb(mtm.getRevoke());

				this.userPrism.getServiceimpl().addMethod(mtm.getListMyActive().generateServiceImplMethod());
				this.userPrism.getDaoimpl().addMethod(mtm.getListMyActive().generateDaoImplMethod());
				this.userPrism.getDummydaoimpl().addMethod(mtm.getListMyActive().generateDummyDaoImplMethod());
				this.userPrism.getAxumController().addMethod(mtm.getListMyActive().generateControllerMethod());
				this.userPrism.getAxumController().addTwoDomainVerb(mtm.getListMyActive());
				
				this.userPrism.getServiceimpl().addMethod(mtm.getListMyAvailableActive().generateServiceImplMethod());
				this.userPrism.getDaoimpl().addMethod(mtm.getListMyAvailableActive().generateDaoImplMethod());
				this.userPrism.getDummydaoimpl().addMethod(mtm.getListMyAvailableActive().generateDummyDaoImplMethod());
				this.userPrism.getAxumController().addMethod(mtm.getListMyAvailableActive().generateControllerMethod());
				this.userPrism.getAxumController().addTwoDomainVerb(mtm.getListMyAvailableActive());
			}
		}
	}

	public Map<String, Boolean> getSlavesMap() {
		return slavesMap;
	}

	public void setSlavesMap(Map<String, Boolean> slavesMap) {
		this.slavesMap = slavesMap;
	}
}
